package drds.plus.executor.command_handler.query;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.command_handler.TableWithIndexMetaData;
import drds.plus.executor.cursor.cursor.ISortingCursor;
import drds.plus.executor.cursor.cursor.impl.common.RangeCursor;
import drds.plus.executor.data_node_executor.DataNodeExecutorContext;
import drds.plus.executor.repository.Repository;
import drds.plus.executor.table.ITable;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.abstract_syntax_tree.configuration.IndexMapping;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Query;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.QueryWithIndex;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.column.Column;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.BooleanFilter;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Filter;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Operation;
import drds.plus.sql_process.abstract_syntax_tree.expression.order_by.OrderBy;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

import java.util.List;

/**
 * 用于处理执行的handler 。 目的是将执行计划中的Query节点进行转义处理。
 * 这个执行器主要是用在使用KV接口的数据库里，比如bdb.concurrentHashMap等。
 */
@Slf4j
public class QueryHandler extends AbstractQueryHandler {
    public Logger log() {
        return log;
    }

    public QueryHandler() {
        super();
    }

    protected ISortingCursor doQuery(ExecuteContext executeContext, ExecutePlan executePlan, ISortingCursor cursor) throws RuntimeException {
        List<OrderBy> orderByList = ((Query) executePlan).getOrderByList();
        Repository repository = executeContext.getRepository();

        QueryWithIndex queryWithIndex = (QueryWithIndex) executePlan;
        ExecutePlan subQuery = queryWithIndex.getSubQuery();
        if (subQuery != null) {
            // 如果有subQuery,则按照subquery构建
            cursor = DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().execute(executeContext, subQuery);
        } else {
            TableWithIndexMetaData tableWithIndexMetaData = new TableWithIndexMetaData();
            prepareTableAndIndexMetaDataForQuery(executeContext, queryWithIndex, tableWithIndexMetaData);
            ITable table = tableWithIndexMetaData.table;
            IndexMapping indexMapping = tableWithIndexMetaData.indexMapping;
            cursor = table.getCursor(executeContext, (QueryWithIndex) executePlan, indexMapping);
        }
        // 获得查询结果的元数据
        // 获得本次查询的keyFilter
        Filter keyFilter = queryWithIndex.getKeyFilter();
        if (keyFilter != null) {
            if (keyFilter instanceof BooleanFilter) {//只有一个表达式 a$b,a in b两种表达式
                cursor = keyFilterToRangeCursor(executeContext, repository, cursor, keyFilter);
            } else {
                cursor = repository.getCursorFactory().rangeCursor(executeContext, cursor, keyFilter);
            }
            if (cursor instanceof RangeCursor) {//这里是针对一个值的时候进行优化
                if (orderByList != null) {
                    if (orderByList.size() == 1) {
                        OrderBy o1 = orderByList.get(0);
                        OrderBy o2 = cursor.getOrderByList().get(0);
                        boolean needSort = !orderByColumnEquals(o1, o2);
                        boolean asc = o1.getAsc();
                        if (!needSort) {//orderByColumnEquals相等
                            if (!asc) {//逆序(可以直接反向取值)
                                // DescRangeCursor
                                cursor = repository.getCursorFactory().reverseOrderCursor(executeContext, cursor);
                            } else {
                                // asc,default
                            }
                            orderByList = null;
                        }
                    }
                }
            }
        }
        return cursor;
    }

    protected ISortingCursor keyFilterToRangeCursor(ExecuteContext executeContext, Repository repository, ISortingCursor cursor, Filter keyFilter) throws RuntimeException {
        BooleanFilter booleanFilter = (BooleanFilter) keyFilter;
        Column column = Utils.getColumn(booleanFilter.getColumn());
        Operation operation = booleanFilter.getOperation();
        if (operation == Operation.in) {
            List<Object> valueList = booleanFilter.getValueList();
            if (valueList == null) {
                throw new IllegalArgumentException("columnValueList is null ,but operation is in . logical error");
            } else {
                return repository.getCursorFactory().inCursor(executeContext, cursor, cursor.getOrderByList(), column, valueList, operation);
            }
        }
        try {
            cursor = repository.getCursorFactory().rangeCursor(executeContext, cursor, keyFilter);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return cursor;
    }

    /**
     * 左数据集和右数据集，排序是否相同。
     */
    protected boolean orderByColumnEquals(OrderBy o1, OrderBy o2) {
        Column c1 = Utils.getColumn(o1.getItem());
        Column c2 = Utils.getColumn(o2.getItem());
        return c1.getTableName().equals(c2.getTableName()) //
                && c1.getColumnName().equals(c2.getColumnName())//
                && o1.getAsc() == o2.getAsc();//
    }
}
